Sources/Source/Components/Sub Navigation/SubNavigationView.swift (121 lines of code) (raw):

// import SwiftUI #if os(iOS) public struct SubNavigationView: View { let items: [SubNavigationItem] let backgroundColor: Color let dividerColor: Color private let horizontalPadding: CGFloat = UIDevice.current.userInterfaceIdiom == .pad ? 184 : 16 @Namespace var namespace @State private var currentItem: SubNavigationItem var selectedItemContent: AnyView? { currentItem.content() } public init( _ items: SubNavigationItem..., startingAt initialItemIndex: Int? = nil, dividerColor: Color = Color( .dynamicColor( light: ColorPalette.neutral73, dark: ColorPalette.neutral38 ) ), backgroundColor: Color = Color( .dynamicColor( light: .white, dark: .black ) ) ) { precondition(items.count >= 2, "We should alway have at least two items in our Subnav") self.items = items self._currentItem = State(initialValue: items[initialItemIndex ?? 0]) self.dividerColor = dividerColor self.backgroundColor = backgroundColor } public var body: some View { VStack(spacing: 0) { selectedItemContent VStack { dividerView() HStack { ForEach(items, id: \.title) { item in Button { } label: { SubNavigationItemView( title: item.title, palette: item.palette, isSelected: item == currentItem, namespace: namespace ) } .buttonStyle(.plain) .simultaneousGesture( TapGesture().onEnded { _ in item.didSelectItem?(currentItem, item) currentItem = item } ) } } .padding(.horizontal, horizontalPadding) dividerView() } .frame(maxHeight: 52) .background(backgroundColor) } } @Environment(\.displayScale) private var displayScale @ViewBuilder private func dividerView() -> some View { Rectangle() .frame(height: 1 / displayScale) .padding(.bottom, 0) .foregroundStyle(dividerColor) } } #Preview { SubNavigationView( SubNavigationItem( title: "Test 1", content: { Text("Test 1") .frame( maxWidth: .infinity, maxHeight: .infinity ) } ), SubNavigationItem( title: "Test 2", content: { Text("Test 2") .frame( maxWidth: .infinity, maxHeight: .infinity ) } ), SubNavigationItem( title: "Test 3", content: { Text("Test 3") .frame( maxWidth: .infinity, maxHeight: .infinity ) } ), SubNavigationItem( title: "Test 4", content: { Text("Test 4") .frame( maxWidth: .infinity, maxHeight: .infinity ) } ) ) } #endif